﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using GameBase;

namespace GalaxyPresident
{
    public class GalaxyLayer : PlayScreenLayer
    {
        SolarSystemView selectingSolarSystem;

        
        List<SolarSystemView> listSolarView=new List<SolarSystemView>();
        bool isFocus = false;
        bool isMoving = false;


        public void initView()
        {
            isFocus = false;
            isMoving = false;
            Layer.Scale = 0.9f;
        }
        public void Focus(SolarSystem ss)
        {
            if(selectingSolarSystem != null)
            {
                selectingSolarSystem.ShowInfo = InfomationType.None;
            }
            foreach (SolarSystemView view in listSolarView)
            {
                if (view.SolarSystem == ss)
                {
                    selectingSolarSystem = view;
                    selectingSolarSystem.ShowInfo = InfomationType.Full;
                    layer.Position = selectingSolarSystem.Position;
                }
            }
            layer.Scale = 2;
        }
        public GalaxyLayer(PlayingScreen playingScreen,Planet forcusedPlanet)
            : base(playingScreen)
        {
            Layer = new Perspective3DGroup(Game.GraphicsDevice.Viewport,250);
            
            //SolarSystemGenerate();
            topLeft = new Vector2(-_playingScreen.MAX_X, -_playingScreen.MAX_Y);
            bottomRight = new Vector2(_playingScreen.MAX_X, _playingScreen.MAX_Y);
            foreach (SolarSystem ss in playingScreen.ListSolarSystem)
            {
                SolarSystemView obj = new SolarSystemView(ss);
                listSolarView.Add(obj);
                Layer.AddChild(obj);
                if (ss == forcusedPlanet.SolarSystem)
                {
                    selectingSolarSystem = obj;
                    obj.ShowInfo = InfomationType.Full;
                }
            }
            for (int i = 0; i < 600; i++)
            {
                int b = 4000;
                int a = 6000;
                int x = Constant.random.Next(2 * a) - a;
                int y = Constant.random.Next(b * 2) - b;
                
                Visble3DObject star = new Visble3DObject(@"Resources/star", 1, 3,
                    new Vector3(x, y, Constant.random.Next(400) - 500));
                star.Sprite.FrameSequence = new List<int> { 0, 1, 2 ,1};
                star.Sprite.CurrentFrame = Constant.random.Next(4);
                star.Sprite.Delay = Constant.random.Next(50) + 50;
                Layer.AddChild(star);
                Layer.Position = selectingSolarSystem.Position;
            }
            for (int i = 0; i < 15; i++)
            {
                int b = 3000;
                int a = 4000;
                int x = Constant.random.Next(2 * a) - a;

                int y = Constant.random.Next(b * 2) - b;

                Visble3DObject star = new Visble3DObject(@"Resources/nebula", 1, 1,
                    new Vector3(x, y, Constant.random.Next(600) - 500));
                star.Scale = (float)(Constant.random.NextDouble()*2 + 1);
                star.Rotate = (float)(Constant.random.NextDouble()*MathHelper.TwoPi);
                star.Sprite.SetOriginPosition(ORIGIN_POSITION.Center);
                Layer.AddChild(star);
            }
            AddChild(Layer);
            Layer.Scale = 2f;
        }
        public void AddToLayer(Visble3DObject obj)
        {
            layer.AddChild(obj);
        }
        public override void Update(GameTime gameTime)
        {
            base.Update(gameTime);
            
            if (isFocus)
            {
                if(selectingSolarSystem != null)
                    Layer.Position = MotionEffects.Move(Layer.Position, selectingSolarSystem.Position, 40);
            }
            if (isMoving)
            {
                if (Layer.Scale < 2f)
                {
                    Layer.Scale *= 1.1f;
                }
                else
                {
                    _playingScreen.ShowSolarLayer(selectingSolarSystem.SolarSystem,true);
                    isMoving = false;
                }
            }
            
        }
        public override void MousePressed(bool onForm)
        {
            base.MousePressed(onForm);
            
            isFocus = false;
        }
        public override void MouseReleased(bool onForm)
        {
            if (isMoving)
                return;
            base.MouseReleased(onForm);
            SolarSystemView currentSolarSys = GetSolarSystemAtCursor();

            if (MouseState.X == pressedPoint.X && MouseState.Y == pressedPoint.Y &&
                currentSolarSys != null)
            {
                if (currentSolarSys == selectingSolarSystem)
                {
                    isMoving = true;
                }
                else
                {
                    selectingSolarSystem = currentSolarSys;

                    FocusOnSelectingSS();

                }
            }
            else
            {
                selectingSolarSystem = null;
            }
        }
        
        public override void MouseHandle()
        {
            base.MouseHandle();

            if (isMoving)
                return;
            foreach (SolarSystemView obj in listSolarView)
            {
                if (obj != selectingSolarSystem)
                {
                    Vector3 pos = obj.GetDrawPosition(
                        ((Perspective3DGroup)Layer).Camara, ((Perspective3DGroup)Layer).Viewport);
                    Rectangle bound = obj.Sprite.GetBound(
                        new Vector2(pos.X, pos.Y), obj.GetDrawScale());
                    if (IsHover(MouseState.X, MouseState.Y, bound))
                    {
                        obj.ShowInfo = InfomationType.Brief;
                    }
                    else
                    {
                        obj.ShowInfo = InfomationType.None;
                    }
                }
            }
            
        }

        private SolarSystemView GetSolarSystemAtCursor()
        {
            foreach (SolarSystemView obj in listSolarView)
            {
                Vector3 pos = obj.GetDrawPosition(
                    ((Perspective3DGroup)Layer).Camara, ((Perspective3DGroup)Layer).Viewport);
                Rectangle bound = obj.Sprite.GetBound(
                    new Vector2(pos.X, pos.Y), obj.GetDrawScale());
                if (IsHover(MouseState.X, MouseState.Y, bound))
                {
                    return obj;
                }
            }
            return null;
        }

        private void FocusOnSelectingSS()
        {
            isFocus = true;
            if(TargetScale<0.5)
                TargetScale = 0.5f;
            selectingSolarSystem.ShowInfo = InfomationType.Full;
        }
        protected override void TranslateScreen(float x, float y)
        {
            Layer.Translate(-x, y);
        }
        protected override Vector2 GetScreenPosition()
        {
            return new Vector2(-Layer.Position.X, Layer.Position.Y);
        }
        protected override void zoomScreen()
        {
            float scrollValue = MouseState.ScrollWheelValue - LastMouseState.ScrollWheelValue;
            if (scrollValue > 0)
            {
                TargetScale /= scaleRate;
            }
            else if (scrollValue < 0)
            {
                TargetScale *= scaleRate;
            }

            float r = Layer.Scale / TargetScale;

            if (r <= scaleSpeed)
            {
                Layer.Scale /= scaleSpeed;
            }
            else if (r >= 1 / scaleSpeed)
            {
                Layer.Scale *= scaleSpeed;
            }
            else
            {
                Layer.Scale = TargetScale;
            }
        }
    }
}
